﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using Yxinmt.Interface;
using Yxinmt.Utility;

namespace Yxinmt.Controls
{
    public class StackPanelButton : BaseControl, IControl
    {
        StackPanel _StackPanel { get; set; }
        Image _Image { get; set; }
        Label _Label { get; set; }
        TextBlock _TextBlock { get; set; }

        private System.Windows.Controls.Button _Button { get; set; }

        public StackPanelButton(Dictionary<string, object> property, IComponent component)
        {
            Property = property;
            _Component = component;
            _Button = new System.Windows.Controls.Button();
            this.Element = _Button;

            _NoContainNameList = new List<string>();
            InitSet();
            SetProperty();
            SetControlProperty();

            this.SetButtonStyle();
        }

        string _PanelFullName { get; set; }

        private void SetButtonStyle()
        {
            Dictionary<string, object> property = new Dictionary<string, object>();
            this.SetPropertyKvp(new List<string> { "Name", "Flow", "BackColor","BackImageUrl", "IsHorizontal" }, property, _NoContainNameList);

            _StackPanel = new StackPanel(property, _Component, true);
            var factory = _StackPanel.GetFactory();
            _PanelFullName = _StackPanel.FullName;

            List<Dictionary<string, object>> propertyList = Property.GetValue<List<Dictionary<string, object>>>("properties");

            string type = string.Empty;
            if (propertyList != null && propertyList.Count > 0)
            {
                propertyList.ForEach(p =>
                {
                    type = p.GetStringValue("type");
                    if (type == "Image")
                    {
                        _Image = new Image(p, _Component, true);
                        factory.AppendChild(_Image.GetFactory());
                    }
                    else if (type == "Label")
                    {
                        if (Property.ContainsKey("Value")) p["Value"] = Property["Value"];
                        _Label = new Label(p, _Component, true);
                        factory.AppendChild(_Label.GetFactory());
                    }
                    else if (type == "TextBlock")
                    {
                        if (Property.ContainsKey("Value")) p["Value"] = Property["Value"];
                        _TextBlock = new TextBlock(p, _Component, true);
                        factory.AppendChild(_TextBlock.GetFactory());
                    }
                });
            }

            System.Windows.Controls.ControlTemplate template = new System.Windows.Controls.ControlTemplate() { VisualTree = factory };

            this.SetTriggers(template.Triggers);

            template.Seal();

            _Button.Template = template;
        }

        private void SetTriggers(System.Windows.TriggerCollection triggers)
        {
            System.Windows.Trigger trigger = null;
            if (Property.GetValue<bool>("IsMouseOver"))
            {
                trigger = new System.Windows.Trigger() { Property = System.Windows.Controls.Button.IsMouseOverProperty, Value = true };

                if (Property.ContainsKey("MouseOverImageUrl"))
                {
                    System.Windows.Setter setter = new System.Windows.Setter();
                    setter.TargetName = _Image.FullName;
                    setter.Property = System.Windows.Controls.Image.SourceProperty;
                    setter.Value = this.GetImage(Property.GetStringValue("MouseOverImageUrl"));
                    trigger.Setters.Add(setter);
                }

                if (Property.ContainsKey("MouseOverBackColor"))
                {
                    System.Windows.Setter setter = new System.Windows.Setter();
                    setter.TargetName = _PanelFullName;
                    setter.Property = System.Windows.Controls.StackPanel.BackgroundProperty;
                    setter.Value = this.GetColor(Property.GetStringValue("MouseOverBackColor"));
                    trigger.Setters.Add(setter);
                }


                if (Property.ContainsKey("MouseOverFontColor"))
                {
                    System.Windows.Setter setter = new System.Windows.Setter();
                    if (_Label != null)
                    {
                        setter.TargetName = _Label.FullName;
                        setter.Property = System.Windows.Controls.Label.ForegroundProperty;
                    }
                    else
                    {
                        setter.TargetName = _TextBlock.FullName;
                        setter.Property = System.Windows.Controls.TextBlock.ForegroundProperty;
                    }
                    setter.Value = new System.Windows.Media.SolidColorBrush(Utility.Common.GetColor(Property.GetStringValue("MouseOverFontColor")));
                    trigger.Setters.Add(setter);
                }

                if (Property.ContainsKey("MouseOverBackImageUrl"))
                {
                    System.Windows.Setter setter = new System.Windows.Setter();
                    setter.TargetName = _PanelFullName;
                    setter.Property = System.Windows.Controls.StackPanel.BackgroundProperty;
                    setter.Value = this.GetImageBrush(Property.GetStringValue("MouseOverBackImageUrl"));
                    trigger.Setters.Add(setter);
                }

                if (_IsButtonStatus)
                {
                    System.Windows.Setter setter = new System.Windows.Setter();
                    setter.TargetName = _PanelFullName;
                    setter.Property = System.Windows.Controls.StackPanel.OpacityProperty;
                    setter.Value = 0.8;
                    trigger.Setters.Add(setter);
                }

                triggers.Add(trigger);
            }

            if (Property.GetValue<bool>("IsPressed"))
            {
                trigger = new System.Windows.Trigger() { Property = System.Windows.Controls.Button.IsPressedProperty, Value = true };

                if (_IsButtonStatus)
                {
                    System.Windows.Setter setter = new System.Windows.Setter();
                    setter.TargetName = _PanelFullName;
                    setter.Property = System.Windows.Controls.StackPanel.OpacityProperty;
                    setter.Value = 0.9;
                    trigger.Setters.Add(setter);
                }

                triggers.Add(trigger);
            }

            trigger = new System.Windows.Trigger() { Property = System.Windows.Controls.Button.IsEnabledProperty, Value = false };

            System.Windows.Setter setter2 = new System.Windows.Setter();
            var backUrl = Property.GetStringValue("GrayBackImageUrl");
            setter2.TargetName = _PanelFullName;
            setter2.Property = System.Windows.Controls.StackPanel.BackgroundProperty;
            if (string.IsNullOrEmpty(backUrl))
            {
                setter2.Value = GetColor("#f2f2f2");
            }
            else
            {
                setter2.Property = System.Windows.Controls.StackPanel.BackgroundProperty;
                setter2.Value = GetImageBrush(backUrl);
            }

            trigger.Setters.Add(setter2);

            if (_Label != null || _TextBlock != null)
            {
                setter2 = new System.Windows.Setter();
                setter2.TargetName = _Label != null ? _Label.FullName : _TextBlock.FullName;
                setter2.Property = System.Windows.Controls.Label.ForegroundProperty;
                setter2.Value = GetColor("#888888");
                trigger.Setters.Add(setter2);
            }

            if (_Image != null)
            {
                setter2 = new System.Windows.Setter();
                setter2.TargetName = _Image.FullName;
                setter2.Property = System.Windows.Controls.Image.SourceProperty;
                var url = Property.GetStringValue("GrayImageUrl");
                setter2.Value = string.IsNullOrEmpty(url)? _Image.GetImageSource(): GetImage(url);
                trigger.Setters.Add(setter2);
            }

            triggers.Add(trigger);
        }

        bool _IsButtonStatus { get; set; }

        public void SetEnabled(bool isEnabled)
        {
            if (_Button.IsEnabled == isEnabled) return;
            _Button.IsEnabled = isEnabled;
        }

        private void SetProperty()
        {
            this.SetDefaultValue("IsClick", true);
            this.SetDefaultValue("Cursor", "Hand");
            this.SetDefaultValue("IsButtonStatus", true);

            _IsButtonStatus = Property.GetValue<bool>("IsButtonStatus");
            if (_IsButtonStatus)
            {
                this.SetDefaultValue("IsMouseOver", true);
                this.SetDefaultValue("IsPressed", true);
            }
        }

        List<string> _NoContainNameList { get; set; }

        protected override void SetProperty(string name, object value)
        {
            System.Windows.Controls.Button c = _Button;
            switch (name)
            {
                case "name": c.Name = string.Concat("btn_", (string)value); break;
                case "Width": c.Width = Convert.ToDouble(value); _NoContainNameList.Add(name); break;
                case "Height": c.Height = Convert.ToDouble(value); _NoContainNameList.Add(name); break;
                case "ControlAlign": SetControlAlign((string)value); _NoContainNameList.Add(name); break;
                case "Dock": System.Windows.Controls.DockPanel.SetDock(c, this.GetDock((string)value)); _NoContainNameList.Add(name); break;
                case "Margin": c.Margin = this.GetThickness((string)value); _NoContainNameList.Add(name); break;
                case "Visible": c.Visibility = (bool)value ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed; _NoContainNameList.Add(name); break;
                case "ZIndex": SetZIndex((int)value); _NoContainNameList.Add(name); break;
                case "Cursor": c.Cursor = GetCursor((string)value); _NoContainNameList.Add(name); break;
                case "CanvasLocation": SetCanvasLocation((string)value); _NoContainNameList.Add(name); break;
                case "CanvasZIndex": SetCanvasZIndex((int)value); _NoContainNameList.Add(name); break;
                case "IsEnabled": c.IsEnabled = (bool)value; break;
            }
        }

        /// <summary>
        /// 事件加载
        /// </summary>
        public override void EventLoad()
        {
            bool isClick = this.Property.GetValue<bool>("IsClick");
            if (isClick) this._Button.Click += _Button_Click;

            bool isDoubleClick = this.Property.GetValue<bool>("IsDoubleClick");
            if (isDoubleClick)
            {
                this._Button.MouseDoubleClick += _Button_MouseDoubleClick;
            }
        }

        void _Button_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            try
            {
                this._Window.DoubleEventInvoke(sender, e, this);
            }
            catch (Exception ex)
            {
                LoggerProxy.Exception(Name, "_Button_MouseDoubleClick", ex);
            }
        }

        void _Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            try
            {
                this._Window.EventInvoke(sender, e, this);
            }
            catch (Exception ex)
            {
                LoggerProxy.Exception(Name, "_Button_Click", ex);
            }
        }

        public void SetImageUrl(string url)
        {
            var image = (System.Windows.Controls.Image)_Button.Template.FindName(_Image.FullName, _Button);
            if (image != null) image.Source = string.IsNullOrEmpty(url) ? null : GetImage(url);
            else
            {
                Task.Run(() =>
                {
                    this._Window.Window.Dispatcher.Invoke(() =>
                    {
                        try
                        {
                            SetImageUrl(url);
                        }
                        catch
                        {
                        }
                    });
                });
            }
        }

        public void SetPanelBackColor(string color)
        {
            var panel = (System.Windows.Controls.StackPanel)_Button.Template.FindName(_StackPanel.FullName, _Button);
            if (panel != null) panel.Background = GetColor(color);
        }

        public void SetFontColor(string color)
        {
            if (_Label != null)
            {
                var label = (System.Windows.Controls.Label)_Button.Template.FindName(_Label.FullName, _Button);
                if (label != null) label.Foreground = GetColor(color);
            }
            else if (_TextBlock != null)
            {
                var label = (System.Windows.Controls.TextBlock)_Button.Template.FindName(_TextBlock.FullName, _Button);
                if (label != null) label.Foreground = GetColor(color); ;
            }
        }

        string _LabelText { get; set; }

        public void SetLabelText(string text)
        {
            _LabelText = text;
            if (_Label != null)
            {
                var label = (System.Windows.Controls.Label)_Button.Template.FindName(_Label.FullName, _Button);
                if (label != null) label.Content = text;
                else
                {
                    Task.Run(() =>
                    {
                        this._Window.Window.Dispatcher.Invoke(() =>
                        {
                            try
                            {
                                SetLabelText(text);
                            }
                            catch
                            {
                            }
                        });
                    });
                }
            }
            else if (_TextBlock != null)
            {
                var label = (System.Windows.Controls.TextBlock)_Button.Template.FindName(_TextBlock.FullName, _Button);
                if (label != null) label.Text = text;
                else
                {
                    Task.Run(() =>
                    {
                        this._Window.Window.Dispatcher.Invoke(() =>
                        {
                            try
                            {
                                SetLabelText(text);
                            }
                            catch
                            {
                            }
                        });
                    });
                }
            }
        }
    }
}
